<template>
  <div class="app-page">
    <div class="app-header">
      <el-radio-group v-model="mode" size="small" @change="change">
        <el-radio-button label="default" border>默认</el-radio-button>
        <el-radio-button label="createEdge" border>创建连线</el-radio-button>
      </el-radio-group>
      <div>
        <el-button type="primary" @click="toggleBg(true)">显示背景</el-button>
        <el-button type="primary" @click="toggleBg(false)">隐藏背景</el-button>
        <el-button type="primary" @click="addNode">添加节点</el-button>
        <el-button type="primary" :disabled="selectedNodes.length ===0" @click="delNodes">删除节点</el-button>
        <el-button type="primary" :disabled="selectedNodes.length !== 2" @click="getShortPath">获取最短路径</el-button>
        <el-button type="primary" @click="getData">保存数据</el-button>
      </div>
    </div>
    <div id="container"></div>
  </div>
</template>

<script>
import G6 from '@antv/g6'
export default {
  data() {
    return {
      mode: 'default',
      index: 0,
      graph: null,
      selectedNodes: [],
      parkingBg: require('@/assets/20231130-102706.jpg')
    }
  },
  mounted() {
    const container = document.getElementById('container')
    const width = container.scrollWidth
    const height = (container.scrollHeight || 500) - 40
    const toolbar = new G6.ToolBar({
      position: { x: 10, y: 10 },
    })
    const snapLine = new G6.SnapLine()

    // 实例化 Grid 插件
    const grid = new G6.Grid()

    this.graph = new G6.Graph({
      container: 'container',
      groupByTypes: false,
      width,
      height,
      linkCenter: true,
      plugins: [grid, toolbar, snapLine],
      // 设置为true，启用 redo & undo 栈功能
      enabledStack: true,
      modes: {
        // 'drag-canvas',
        default: [
          'drag-canvas',
          'click-select',
          'drag-node',
        ],
        // 创建连线
        createEdge: [
          {
            type: 'create-edge',
            trigger: 'drag', // 'click' by default. options: 'drag', 'click'
          },
        ],
        // // 操作画布
        // canvas: [
        //   'drag-canvas',
        //   'zoom-canvas',
        // ],
      },
      defaultNode: {
        style: {
          size: [2, 2],
        },
      },
      defaultEdge: {
        style: {
          stroke: '#F6BD16',
          lineWidth: 2,
        },
      },
      fitView: false,
    })

    // this.graph.setImageWaterMarker(require('@/assets/20231130-102706.jpg'),
    //   {
    //     width: 1451,
    //     height: 486,
    //     image: { x: 0, y: 0, width: 1451, height: 486, rotate: 0 },
    //   }
    // )

    // const dataBg = {
    //   nodes: [
    //     { id: 'nodebg', x: 0, y: 0, type: 'dom-node' }
    //   ],
    //   edges: [],
    //   combos: []
    // }
    // this.graph.data(dataBg)
    // this.graph.render()
    // const node = this.graph.findById('nodebg')
    // node.lock()

    // if (this.graph) {
    //   return
    // }

    // const canvas = this.graph.get('canvas')
    // console.log(canvas)

    // group.addShape('image', {
    //   attrs: {
    //     x: 0,
    //     y: 0,
    //     img: 'https://g.alicdn.com/cm-design/arms-trace/1.0.155/styles/armsTrace/images/TAIR.png',

    //   },
    //   // 在 G6 3.3 及之后的版本中，必须指定 name，可以是任意字符串，但需要在同一个自定义元素类型中保持唯一性
    //   name: 'image-shape',
    // })
    // 'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg'
    try {
      console.log(localStorage.getItem('graphData'))
      const data = localStorage.getItem('graphData')
        ? JSON.parse(localStorage.getItem('graphData'))
        : {
            nodes: [
              {
                id: 'parkingBg',
                img: require('@/assets/20231130-102706.jpg'),
                x: 1451,
                y: 486,
                type: 'image',
                size: [1451 * 2, 486 * 2],
              },
            ],
            edges: [],
            combos: []
          }
      this.graph.data(data)
      this.graph.render()
      const node = this.graph.findById('parkingBg')
      if (node) {
        node.toBack()
        node.lock()
        node.enableCapture(false)
      }
    } catch (error) {
      console.log(error)
    }

    this.graph.on('nodeselectchange', e => {
      // console.log(e.selectedItems, e.select)
      this.selectedNodes = e.selectedItems.nodes
    })

    this.graph.on('canvas:click', e => {
      this.clearStates()
      this.selectedNodes = []
    })
  },
  methods: {
    // 放大缩小
    toggleBg(show) {
      if (show) {
        const model = {
          id: 'parkingBg',
          img: require('@/assets/20231130-102706.jpg'),
          x: 1451,
          y: 486,
          type: 'image',
          size: [1451 * 2, 486 * 2],
        }

        this.graph.addItem('node', model)
        const item = this.graph.findById('parkingBg')
        item.toBack()
        item.lock()
        item.enableCapture(false)
      } else {
        const item = this.graph.findById('parkingBg')
        this.graph.removeItem(item)
      }
    },
    clearStates () {
      this.graph.getNodes().forEach(node => {
        this.graph.clearItemStates(node)
      })
      this.graph.getEdges().forEach(edge => {
        this.graph.clearItemStates(edge)
      })
    },
    getData() {
      console.log(this.graph.save())
      const data = this.graph.save()
      localStorage.setItem('graphData', JSON.stringify(data))
      // console.log(this.graph.data)
    },
    addNode() {
      const point = this.graph.getViewPortCenterPoint()
      console.log('图内容中心的绘制坐标是', point.x, point.y)

      this.graph.addItem('node', {
        id: 'node' + new Date().getTime(),
        x: point.x,
        y: point.y,
      })
    },
    delNodes() {
      console.log(this.selectedNodes)
      this.selectedNodes.forEach(node => {
        this.graph.removeItem(node, false)
      })
    },
    getShortPath() {
      this.clearStates()
      console.log('获取最短节点')
      const { findShortestPath } = G6.Algorithm
      const selectedNodeIds = this.selectedNodes.map(ele => {
        return ele.getID()
      })
      // path 为其中一条最短路径，allPath 为所有的最短路径
      const { path, allPath } = findShortestPath(
        this.graph.save(),
        selectedNodeIds[0],
        selectedNodeIds[1],
        false
      )
      if (path?.length) {
        const pathNodeMap = {}
        path.forEach(id => {
          const pathNode = this.graph.findById(id)
          pathNode.toFront()
          this.graph.setItemState(pathNode, 'highlight', true)
          pathNodeMap[id] = true
        })
        this.graph.getEdges().forEach(edge => {
          const edgeModel = edge.getModel()
          const source = edgeModel.source
          const target = edgeModel.target
          const sourceInPathIdx = path.indexOf(source)
          const targetInPathIdx = path.indexOf(target)
          if (sourceInPathIdx === -1 || targetInPathIdx === -1) return
          if (Math.abs(sourceInPathIdx - targetInPathIdx) === 1) {
            this.graph.setItemState(edge, 'highlight', true)
          } else {
            this.graph.setItemState(edge, 'inactive', true)
          }
        })
        this.graph.getNodes().forEach(node => {
          if (!pathNodeMap[node.getID()]) {
            this.graph.setItemState(node, 'inactive', true)
          }
        })
      } else {
        this.$message.warning('没有找到路径')
      }
    },
    // 切换模式
    change(e) {
      // console.log(e)
      this.graph.setMode(e)
    }
  }
}
</script>

<style lang="scss" scoped>
.app-page{
  height: 100%;
}
.app-header{
  padding: 10px;
  padding-left: 300px;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
#container{
  height: 486px;
  width: 1451px;
  // position: relative;
  // background-color: #f8f8f8;
  // background-image: url('~@/assets/20231130-102706.jpg');
  // background-position: left top;
  // background-repeat: no-repeat;
  // background-size: 200% 200%;
}
</style>
